package init;

import java.io.File;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.datasource.FileRefreshableDataSource;
import com.alibaba.csp.sentinel.datasource.ReadableDataSource;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;

@WebListener
public class MyServletContextListener implements ServletContextListener {
	String flowRulePath = "D:/RuleWithModePullByFile-flow-rule.json";
//			getClass().getResource("/").getPath() + "/SENTINEL-REULS/flow-rule.json"; //部署的执行路径

	@Override
	public void contextInitialized(ServletContextEvent sce) {
		System.out.println("MyServletContextListener监听到项目初始化完成");
		System.out.println("手动注册Sentinel的DataSource数据源");
		try {
			// 流控规则转化器
			Converter<String, List<FlowRule>> fileRulesConverter = new Converter<String, List<FlowRule>>() {
				@Override
				public List<FlowRule> convert(String source) {
					try {
						System.out.println("读取：" + source);
						ObjectMapper objectMapper = new ObjectMapper();
						JavaType javaType = objectMapper.getTypeFactory().constructParametricType(ArrayList.class, FlowRule.class);
						List<FlowRule> readValue = objectMapper.readValue(source, javaType);
						return readValue;
					} catch (JsonProcessingException e) {
						e.printStackTrace();
					}
					return null;
				}
			};
			
			// 创建流控规则的FileRefreshableDataSource(读DataSource)
			ReadableDataSource<String, List<FlowRule>> flowRuleRDS =
//           	new FileRefreshableDataSource<>( flowRulePath, fileRulesConverter );
					new FileRefreshableDataSource<>(new File(flowRulePath), fileRulesConverter, 3000, 1024 * 1024, Charset.forName("utf-8"));
			// 将可读数据源注册至FlowRuleManager
			// 这样当规则文件发生变化时，就会更新规则到内存
			FlowRuleManager.register2Property(flowRuleRDS.getProperty());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public void contextDestroyed(ServletContextEvent sce) {
		System.out.println("MyServletContextListener监听到项目销毁");
	}
}